<?php
namespace app\api\controller;

use think\Controller;
use think\Db;
use think\Exception;

class Vippay extends Controller
{
    public $wxpay;
    public $user_id;

    public function _initialize()
    {
        parent::_initialize();
        error_reporting(0);
        // 制定允许其他域名访问
        header("Access-Control-Allow-Origin:*");
        // 允许的响应类型
        header('Access-Control-Allow-Methods: GET, POST, PUT,DELETE,OPTIONS,PATCH');
        // 响应头设置
        header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization");
        $this->wxpay = db('weixin_config')->find(1);
        $this->user_id = session("user_id");

    }

    //微信支付
    public function pay()
    {   
         
        if (!$this->is_weixin()) {
            return json(['code' => 0, 'msg' => '请使用微信授权登录']);
        }

        if (!$this->user_id) {
            return json(['code' => -1, 'msg' => '请登录']);
        }

        //获取参数
        $upgrade_number = input('upgrade_number');

        $orderinfo = db('vip_upgrade')->where(['upgrade_number' => $upgrade_number,'status'=>0])->find();

        if (empty($orderinfo)) {
            return json(['code' => 0, 'msg' => '订单信息错误']);
        }

            
        
        
        $user = db('user')->where(['user_id'=>$this->user_id])->find();
        
        //查询卡片 
        $card = db('vip_cate') 
            ->where(['id'=>$orderinfo['card_id'],'status'=>0])
            ->find();
    
        if(empty($card)){
            return json(['code' => 0, 'msg' => '该会员卡已下架']);
        }
        
        //查询用户当前的等级和会员卡的等级
        if($user['vip_id']>=$card['level']){
            return json(['code' => 0, 'msg' => '您的会员等级过高']);
        }
        
        $notify_url = request()->server("REQUEST_SCHEME") . "://" . $_SERVER['SERVER_NAME'] . '/api/vippay/wxnotify';

        //构造微信支付
        $param = [
            'mch_id' => $this->wxpay['mch_id'],
            'appid' => $this->wxpay['wx_appid'],
            'nonce_str' => $this->_tool_random(32),
            'body' => '禅寓酒店会员升级',
            'out_trade_no' => $orderinfo['upgrade_number'],
            'total_fee' => intval($orderinfo['money'] * 100),
            //'total_fee' => 0.01*100,
            'notify_url' => $notify_url,
            'trade_type' => 'JSAPI',
            'spbill_create_ip' => request()->ip(),
            'openid' => $user['openid'],
        ];

        $stringA = $this->artxun_param_sort($param) . '&key=' . $this->wxpay['wx_key'];
        $param['sign'] = strtoupper(md5($stringA));
        //统一下单
        $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
        $post_data = "<xml>
                        <appid>{$param['appid']}</appid>
                        <body>{$param['body']}</body>
                        <mch_id>{$param['mch_id']}</mch_id>
                        <nonce_str>{$param['nonce_str']}</nonce_str>
                        <notify_url>{$param['notify_url']}</notify_url>
                        <out_trade_no>{$param['out_trade_no']}</out_trade_no>
                        <spbill_create_ip>{$param['spbill_create_ip']}</spbill_create_ip>
                        <total_fee>{$param['total_fee']}</total_fee>
                        <trade_type>{$param['trade_type']}</trade_type>
                        <openid>{$param['openid']}</openid>
                        <sign>{$param['sign']}</sign>
                    </xml>";

        $dataxml = $this->http_post($url, $post_data);
        $json = (array) simplexml_load_string($dataxml, 'SimpleXMLElement', LIBXML_NOCDATA); //将微信返回的XML 转换成数组

        $time = time();
        if (is_array($json)) {
            if ($json['result_code'] == 'SUCCESS') {
                $jsApiParameters = [
                    "appId" => $json['appid'],
                    "timeStamp" => "{$time}",
                    "nonceStr" => $this->_tool_random(32),
                    "package" => "prepay_id={$json['prepay_id']}",
                    "signType" => "MD5",
                ];
                $stringA = $this->artxun_param_sort($jsApiParameters) . '&key=' . $this->wxpay['wx_key'];
                $sing = strtoupper(md5($stringA));
                $jsApiParameters['paySign'] = $sing;
                //返回参数
                return json([
                    'code' => 1,
                    'data' => json_encode($jsApiParameters)
                ]);
            }
            return json(['code' => 0, 'msg' => '错误']);
        }
        return json(['code' => 0, 'msg' => '下单错误 稍后再试']);

    }

    //异步回调
    public function wxnotify()
    {

        //获取微信返回参数
        $xmlData = file_get_contents('php://input');
        //file_put_contents("notify.log",$xmlData."\n",FILE_APPEND);
        libxml_disable_entity_loader(true);
        $param = (array) simplexml_load_string($xmlData, 'SimpleXMLElement', LIBXML_NOCDATA);

        $sign = isset($param['sign']) && !empty($param['sign']) ? trim($param['sign']) : null;
        unset($param['sign']);

        $stringA = $this->artxun_param_sort($param) . '&key=' . $this->wxpay['wx_key'];
        if (strtoupper(md5($stringA)) != $sign) {
            file_put_contents('notify.log', '签名错误' . "\n", FILE_APPEND);
            return '签名错误';
        }
        $status = $param['result_code'];
        if ($status == 'SUCCESS') {
            $ordersn = $param['out_trade_no'];
            if ($this->check_order($ordersn)) {

                echo "<xml>
                            <return_code><![CDATA[SUCCESS]]></return_code>
                            <return_msg><![CDATA[OK]]></return_msg>
                        </xml>";
                exit();
            } else {
                file_put_contents("notify.log", 'error' . date("Y-m-d H:i:s") . "\n", FILE_APPEND);
            }

        }

    }

    //改变订单状态
    public function check_order($out_trade_no)
    {   
         
        //查询订单
        $order = db('vip_upgrade')->where(['upgrade_number' => $out_trade_no])->find();
        if($order['status']==0){
            //改变订单状态
            db("vip_upgrade")->where(['upgrade_number' => $out_trade_no])->update(['status' => 1, 'paytime' => time()]);
            
             
            //更改用户的vip的等级
            db("user")->where(['user_id' => $order['user_id']])->update(['vip_id' => $order['new_level']]);
            
            //用户消费记录表加数据
            moneyLog($order['user_id'],$order['money'],6,0,$order['upgrade_number'],"会员升级");
        }
          
        
        //用户升级逻辑
        // checkLevel($order['user_id']);

    }

    //参数排序
    public function artxun_param_sort(array &$params)
    {
        if (!ksort($params)) {
            throw new Exception('参数排序失败');
        }
        $arr_temp = array();
        foreach ($params as $k => $v) {
            if (is_array($v)) {
                $sarr_temp = array();
                foreach ($v as $kk => $vv) {
                    if (!ksort($vv)) {
                        throw new Exception('参数排序失败');
                    }

                    foreach ($vv as $dk => $dv) {
                        $sarr_temp[] = "{$dk}={$dv}";
                    }
                }
                $arr_temp[] = sprintf('%s=%s', $k, implode('&', $sarr_temp));
            } else {
                $arr_temp[] = "{$k}={$v}";
            }

        }
        // 将数组拼接成字符串，以key=value&key=value的形式进行拼接，注意这里不能直接调用
        // http_build_query方法，因为该方法会对参数进行URL编码
        return implode('&', $arr_temp);
    }

    /**
     * 取得提定长度的随机数字组成的字符串
     */
    public function _tool_random($length = 5)
    {
        $hash = '';
        $chars = '0123456789';
        $max = strlen($chars) - 1;
        mt_srand((double) microtime() * 1000000);
        for ($i = 0; $i < $length; $i++) {
            $hash .= $chars[mt_rand(0, $max)];
        }
        return $hash;
    }

    public function http_post($url, $data)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        $res = curl_exec($ch);
        curl_close($ch);
        return $res;
    }

    //是否微信浏览器
    public function is_weixin()
    {
        if (strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') !== false) {
            return true;
        }
        return false;
    }

}
